package com.qianxx.viewlibrary.chart.statistical;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
import android.view.View;

import com.qianxx.viewlibrary.R;

import java.text.DecimalFormat;

/**
 * 垂直数据统计条
 */
public class StatisticalBar extends View implements Animator.AnimatorListener {
    //画笔
    private Paint paint;
    //柱状条景色
    private int columnarColor = Color.WHITE;
    //柱状条的宽度
    private int columnarWidth = 15;
    //控件宽度
    private int width;
    //控件高度
    private int height;
    //当前进度的百分比
    private double percent;
    //动画持续时间
    private long duration = 1500;
    //最大数值
    private double maxValue;
    //当前数值
    private double curValue;
    //字体颜色
    private int textColor = Color.WHITE;
    //字体大小
    private float textSize = 26;
    //文字与柱状条的间距
    private float textMargin = 45;
    //保留2位小数
    private DecimalFormat decimalFormat = new DecimalFormat("0.00");
    //指示器背景色
    private int indicatorColor = Color.RED;
    //指示器与文字的内边距
    private int indicatorPadding = 15;
    //倒三角的宽度
    private int triangleWidth = 15;
    //倒三角的高度
    private int triangleHeight = 10;
    //是否显示指示器
    private boolean isShowIndicator = false;

    public StatisticalBar(Context context) {
        this(context, null);
    }

    public StatisticalBar(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public StatisticalBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.StatisticalBar);
        columnarColor = ta.getColor(R.styleable.StatisticalBar_columnar_Color, Color.WHITE);
        columnarWidth = (int) ta.getDimension(R.styleable.StatisticalBar_columnar_Width, 15);
        textSize = ta.getDimension(R.styleable.StatisticalBar_text_Size, 26);
        textColor = ta.getColor(R.styleable.StatisticalBar_text_Color, Color.WHITE);
        indicatorColor = ta.getColor(R.styleable.StatisticalBar_indicator_Color, Color.RED);
        ta.recycle();

        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTextSize(textSize);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = MeasureSpec.getSize(widthMeasureSpec);
        height = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(getTextWidth() > columnarWidth ? getTextWidth() : columnarWidth, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        try {
            //绘制背景柱状条
            drawBackground(canvas);
            //绘制前景柱状条
            drawForeground(canvas);
            //绘制指示器
            if (isShowIndicator)
                drawIndicator(canvas);
            //绘制文字
            drawText(canvas);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 绘制背景柱状条
     *
     * @param canvas
     */
    private void drawBackground(Canvas canvas) {
        paint.setColor(columnarColor);
        paint.setAlpha(80);

        float left = (getTextWidth() - columnarWidth) / 2;
        float top = 0;
        float right = (getTextWidth() + columnarWidth) / 2;
        float bottom = height;

        RectF background = new RectF();
        background.left = left;
        background.top = top;
        background.right = right;
        background.bottom = bottom;
        canvas.drawRoundRect(background, 45, 45, paint);
    }

    /**
     * 绘制前景柱状条
     *
     * @param canvas
     */
    private void drawForeground(Canvas canvas) {
        paint.setColor(columnarColor);
        paint.setAlpha(255);

        float left = (getTextWidth() - columnarWidth) / 2;
        float top = (float) (height - height * curValue / maxValue * percent);
        float right = (getTextWidth() + columnarWidth) / 2;
        float bottom = height;

        RectF background = new RectF();
        background.left = left;
        background.top = top;
        background.right = right;
        background.bottom = bottom;
        canvas.drawRoundRect(background, 45, 45, paint);
    }

    /**
     * 绘制指示器部分（由圆角矩形和倒三角形组成）
     *
     * @param canvas
     */
    private void drawIndicator(Canvas canvas) {
        paint.setColor(indicatorColor);
        paint.setAlpha(255);

        float left = 0;
        float top = (float) (height - height * curValue / maxValue * percent) - textMargin - getTextHeight() - indicatorPadding;
        float right = getTextWidth();
        float bottom = (float) (height - height * curValue / maxValue * percent) - textMargin + indicatorPadding;

        top = bottom < getTextHeight() + indicatorPadding * 2 ? 0 : top;
        bottom = bottom < getTextHeight() + indicatorPadding * 2 ? getTextHeight() + indicatorPadding * 2 : bottom;

        //绘制圆角矩形部分
        RectF background = new RectF();
        background.left = left;
        background.top = top;
        background.right = right;
        background.bottom = bottom;
        canvas.drawRoundRect(background, 5, 5, paint);

        float x1 = getTextWidth() / 2 - triangleWidth;
        float y1 = (float) (height - height * curValue / maxValue * percent) - textMargin + indicatorPadding - 1;
        float x2 = getTextWidth() / 2 + triangleWidth;
        float y2 = y1;
        float x3 = getTextWidth() / 2;
        float y3 = (float) (height - height * curValue / maxValue * percent) - textMargin + indicatorPadding + triangleHeight;

        y1 = y3 < bottom + triangleHeight ? bottom : y1;
        y2 = y3 < bottom + triangleHeight ? bottom : y2;
        y3 = y3 < bottom + triangleHeight ? bottom + triangleHeight : y3;

        //绘制倒三角形部分
        Path path5 = new Path();
        path5.moveTo(x1, y1);
        path5.lineTo(x2, y2);
        path5.lineTo(x3, y3);
        path5.close();
        canvas.drawPath(path5, paint);
    }

    /**
     * 绘制文字
     *
     * @param canvas
     */
    private void drawText(Canvas canvas) {
        paint.setColor(textColor);
        paint.setAlpha(255);

        String text = "￥" + twodecimalPlaces(curValue * percent + "");
        float x = indicatorPadding;
        float y = (float) ((height - height * curValue / maxValue * percent) - textMargin);

        float indicatorBottom = (float) (height - height * curValue / maxValue * percent) - textMargin + indicatorPadding;
        indicatorBottom = indicatorBottom < getTextHeight() + indicatorPadding * 2 ? getTextHeight() + indicatorPadding * 2 : indicatorBottom;
        y = y < indicatorBottom / 2 ? indicatorBottom / 2 + getTextHeight() / 2 : y;

        canvas.drawText(text, x, y, paint);
    }

    /**
     * 获取文字的总宽度
     *
     * @return
     */
    private int getTextWidth() {
        Rect rect = new Rect();
        String text = "￥" + twodecimalPlaces(curValue + "") + "&" + indicatorPadding;
        paint.getTextBounds(text, 0, text.length(), rect);
        return rect.width();
    }

    /**
     * 获取文字的总高度
     *
     * @return
     */
    private int getTextHeight() {
        Rect rect = new Rect();
        String text = "￥" + twodecimalPlaces(curValue + "") + "&";
        paint.getTextBounds(text, 0, text.length(), rect);
        return rect.height();
    }

    /**
     * 设置最大进度值
     *
     * @param maxValue
     */
    public void setMaxValue(double maxValue) {
        this.maxValue = maxValue;
    }

    /**
     * 设置当前进度值
     *
     * @param curValue
     */
    public void setCurValue(double curValue) {
        this.curValue = curValue;
        startAnimation();
    }

    /**
     * 保留2位小数
     *
     * @param number
     * @return
     */
    public String twodecimalPlaces(String number) {
        return decimalFormat.format(Double.parseDouble(number));
    }

    /**
     * 开始执行动画
     */
    private void startAnimation() {
        setLayerType(LAYER_TYPE_HARDWARE, null);

        ObjectAnimator an = ObjectAnimator.ofFloat(this, "percent", 0, 1);
        an.setInterpolator(new FastOutSlowInInterpolator());
        an.addListener(this);
        an.setDuration(duration);
        an.start();
    }

    public double getPercent() {
        return percent;
    }

    public void setPercent(float percent) {
        this.percent = percent;
        invalidate();
    }

    public boolean isShowIndicator() {
        return isShowIndicator;
    }

    public void setShowIndicator(boolean showIndicator) {
        isShowIndicator = showIndicator;
    }

    @Override
    public void onAnimationStart(Animator animation) {

    }

    @Override
    public void onAnimationEnd(Animator animation) {
        setLayerType(LAYER_TYPE_NONE, null);
    }

    @Override
    public void onAnimationCancel(Animator animation) {

    }

    @Override
    public void onAnimationRepeat(Animator animation) {

    }
}
